/* Copyright 2010 the original author or authors.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package activiti

import org.codehaus.groovy.grails.web.json.JSONArray
import org.codehaus.groovy.grails.web.json.JSONObject
import system.Authority

/**
 *
 * @author <a href='mailto:limcheekin@vobject.com'>Lim Chee Kin</a>
 *
 * @since 5.0.beta2
 */
class ActSolutionService {
    def utilsService
    def activitService

    def saveOrUpdate(params) {

        def map = [:]
        map.putAll(params)
        ActSolution actSolution
        if (utilsService.isNumber(params.id)&&params.id?.toString()!='0') actSolution = ActSolution.get(params.id as long)
        else actSolution = new ActSolution()
        actSolution.properties = utilsService.changeParams(actSolution, map)
//        def existBm=ActSolution.findAll("from  ActSolution where bm=:bm  and id!=:id and fromId=:fromId",[bm:actSolution.bm,id: (actSolution.id?:0.toLong()),fromId: (actSolution.fromId?:0.toInteger())])?.find {true}
//        if (existBm) throw  new RuntimeException("别名已被 方案 ${existBm.name} 使用,请重新命名")
        if (!actSolution.save(flush: true)) {
            actSolution.errors.each {
                log.error(it)
            }
        }
        if (utilsService.validString(params.rds)) {
            JSONArray jsonArray = new JSONArray(params.rds)
            JSONObject jsonObject
            jsonArray.eachWithIndex { it, i ->
                log.debug("it->" + it)
                jsonObject = new JSONObject(it)
                ActSolutionMx mx = new ActSolutionMx()
                if (params.id?.toString()=='0'||!utilsService.validString(params.id)){ it.remove('id') }
                def id = it.optLong('id')
                if (id) mx = ActSolutionMx.get(id)
                mx.properties = utilsService.changeParams(mx, it)
//                mx.formName = mx.openJs?.jsName
//                mx.formXtype = mx.openJs?.jsXtype
                if (!id) actSolution.addToMx(mx)
                if (!mx.save()) {
                    mx.errors.each { err ->
                        log.error(err)
                        throw new IllegalArgumentException('保存明细异常' + err)
                    }
                }
            }
        }
        if (!actSolution.save(flush: true)) {
            actSolution.errors.each {
                log.error(it)
            }
        }
        ActModel actModel=actSolution.actModel
        if (actModel){
//            actModel.openJs=actSolution.mx.find {it.isStartTask=='1'}?.openJs
            if (!actModel.save(flush: true)) {
                actModel.errors.each {
                    log.error(it)
                }
            }
        }
    }

    //据业务解决方案 发布后 写 权限和windowConfig
//   入参: id (方案 id)
    def saveAuthorityWindowConfig(map) {
        ActSolution actSolution = ActSolution.get(map.id as long)
        ActModel actModel = actSolution.actModel
        ActSolutionMx asm = actSolution.mx?.find{it.isStartTask=='1'}
        def AuthorityList = Authority.findAllByActSolutionId(actSolution.id)
        AuthorityList.each {
            it.sfsx='0'
            it.save(flush: true)
        }
        if (actModel) {
            Authority pauthority = Authority.findByAuthority(actModel.key)
            if (!pauthority) {
                pauthority = new Authority(authority: actModel.key, showName: actModel.name)
                pauthority.id = actModel.key
                pauthority.type = "目录"
                pauthority.actSolutionId=actSolution.id
                pauthority.showToJm = true
                pauthority.xmmc=asm?.openJs?.xmmc
                pauthority.sfsx = '1'

            }else{
                pauthority.actSolutionId=actSolution.id
                pauthority.xmmc=asm?.openJs?.xmmc
                pauthority.sfsx='1'
            }
            if (!pauthority.save()) {
                pauthority.errors.each {
                    log.error(it)
                }
            }
            log.debug(pauthority.properties.toString())
            def mxList = actSolution.mx.sort { a, b -> a.id <=> b.id }
            def appName = utilsService.appName
            mxList.each {
                Authority authority = Authority.findByAuthority(it.taskId)
                if (!authority) authority = new Authority()
                authority.id = it.taskId
                authority.actSolutionId=actSolution.id
                authority.authority = it.taskId
                authority.url = it.fqActionUrl
                authority.xmmc=asm?.openJs?.xmmc
                if (authority.url) {
                    authority.showToJm = true
                    if (!authority.url.contains("/" + appName))
                        authority.url = "/" + appName + authority.url
                }
                else authority.showToJm = false
                authority.showName = it.taskName
                authority.parent = pauthority
                authority.sfsx = '1'
                log.debug(authority.properties.toString())
                if (!authority.save()) {
                    authority.errors.each {
                        log.error(it)
                    }
                }
            }
            // 重新创建 WindowConfig时为了减少无效的数据,要流程删除改流程的数据
            def list=[]
            list.addAll(WindowConfig.findAllByProcessName(actModel.key))
            list.each {
                it.delete(flush: true)
            }

            def startMx = mxList.find { it.isStartTask == '1' }
            def writeMx = mxList.find { it.isWriteTzTask == '1' }
            mxList.each {
                WindowConfig windowConfig = WindowConfig.findByStepName(it.taskId)
                if (!windowConfig) windowConfig = new WindowConfig(stepName: it.taskId)
                windowConfig.tacheFormName = (it.formXtype?:it?.openJs?.jsXtype)
                windowConfig.processNameZh = actModel.name
                windowConfig.processName = actModel.key
                windowConfig.startStepName = (startMx.formXtype?:startMx?.openJs?.jsXtype)
                if (windowConfig.stepName == startMx.taskId) windowConfig.isStartTask = 1
                else windowConfig.isStartTask = 0
                if (windowConfig.stepName == writeMx.taskId) windowConfig.isWriteTzTask = 1
                else windowConfig.isWriteTzTask = 0
                windowConfig.saveURL = "/"+startMx.openJs?.controlerName+"/save"
                if (!windowConfig.saveURL.contains("/" + appName))
                    windowConfig.saveURL = "/" + appName + windowConfig.saveURL
                windowConfig.xmmc = it.openJs?.xmmc
                windowConfig.picURL = "/activit/getModelPic?id=" + actModel.id
                if (!windowConfig.picURL.contains("/" + appName))
                    windowConfig.picURL = "/" + appName + windowConfig.picURL
                log.debug(windowConfig.properties.toString())
                if (!windowConfig.save()) {
                    windowConfig.errors.each {
                        log.error(it)
                    }
                }
            }

        }

    }
    // 部署方案,同时 部署 流程定义
    def deploy(params) {
        def id = (params.id as long)
        ActSolution actSolution = ActSolution.get(id)
        if (!actSolution.actModel?.id) throw new RuntimeException("没有流程定义,不能发布")
        ActSolutionMx startasm = actSolution.mx?.find{it.isStartTask=='1'}
        ActSolutionMx endasm = actSolution.mx?.find{it.isWriteTzTask=='1'}
        if (!startasm) throw new RuntimeException("没有定义发起环节,不能发布！")
        if (!endasm) throw new RuntimeException("没有定义写台账环节,不能发布！")

        actSolution.status = "已发布"
        actSolution.fbsj = new Date()
        if (!actSolution.save()) {
            actSolution.errors.each {
                log.error(it)
            }
        }
        activitService.deploy([request: params.request, id: actSolution.actModel?.id])
        saveAuthorityWindowConfig([id: id])
        //  Actmodel中 其他 controlerName 相同的模型装台改为 新建 (即:模型中 相同业务的只能同时存在一个是发布的)
        def list=[]
        list.addAll(ActModel.findAll("from   ActModel where openJs.controlerName=:controlerName  and id!=:id",[controlerName:actSolution.actModel.openJs?.controlerName, id:actSolution.actModel.id]))
        def otherSolutions=ActSolution.findAll("from  ActSolution  where actModel.openJs.controlerName=:controlerName and id!=:id",[controlerName:actSolution.actModel.openJs?.controlerName, id:actSolution.id])
        list.each { ActModel actModel->
            actModel.status='新建'
            if (!actModel.save()) {
                actModel.errors.each {
                    log.error(it)
                }
            }
        }
        otherSolutions.each {
            it.status='新建'
            if (!it.save()) {
                it.errors.each {
                    log.error(it)
                }
            }
        }

        return true
    }
    def changeSyApp(map){
        ActSolution.executeUpdate("update  ActSolution  set syApp=:syApp  where id in (:idList)",[syApp:map.syApp, idList:map.ids.toString().split(",").collect{it as long}])
    }
}
